import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCInsertDemo {
    public static void main(String[] args) throws SQLException { // 这里main方法的throws意思是让JVM自己处理
        // 使用 jdbc 往数据库中，插入一个记录
        // 需要提前准备好 数据库(java106) 和数据表(student)

         /**1. 创建数据源，描述了数据库服务器在哪*/
        // 写法1：这样写可以使后续代码使用 DataSource 类型的实例，避免 MysqlDataSource 这个名字扩散
        //       到代码的各个地方，实现（高内聚），未来要是换数据库，就只改动这一个代码即可。
        DataSource dataSource = new MysqlDataSource(); // 向上转型 -- 父类的引用指向子类的实例
        // 设置数据库所在位置，当前是固定写法.  127.0.0.1：“环回ip”，只要数据库服务器和 jdbc程序 在同一个电脑上，就可以使用这个ip
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java106?characterEncoding=utf8&useSSL=false"); //向下转型 -- 把父类又转换为子类的类型
        // Url -- 唯一资源地址符，描述了互联网的唯一的一个资源的位置，也就是网址   useSSL=false -- 关闭加密功能，此处不必加密，手动关闭，如果不关，可能连接失败。
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456"); //此处的set...这3个方法都是子类 MysqlDataSource 的方法
        // 写法2：可以不做任何转型，直接 new MysqlDataSource 就可以直接用了 --- 适用于当前不切换数据库的情况下
        /*MysqlDataSource mysqlDataSource = new  MysqlDataSource();
        mysqlDataSource.setUrl();*/

        /**2. 和数据库建立网络连接。（写的 jdbc 代码实质上是 实现一个 mysql 客户端，要通过网络和服务器进行通讯）*/
        // Connection 是网络通讯中的核心概念，叫做“连接”（Connection），找个地方记录下哪个客户端和哪个服务器即将要进行通讯
        Connection connection = dataSource.getConnection();

        // 通过控制台，来输入用户的信息
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入学号：");
        int id = scanner.nextInt();
        System.out.println("请输入姓名：");
        String name = scanner.next();

        /**3. 构造一个 SQL 语句，来完成插入操作*/
        String sql = "insert into student values(?,?)";
        // jdbc 中还需要搭配一个特定的对象，来描述这里的 SQL 的情况
        PreparedStatement statement = connection.prepareStatement(sql); // 每次执行SQL语句都要构造一次，PreparedStatement会对SQL语句做一些预处理，比如解析语句
        statement.setInt(1,id);       // 指把第一个占位符替换成 id
        statement.setString(2,name);  // 指把第二个占位符替换成 name
        System.out.println("sql: " + statement);

        /**4. 执行 SQL 语句。（控制客户端给服务器发送网络请求）针对 增、删、改 使用 executeUpdate 来执行，针对 查 使用 executeQuery 来执行*/
        int ret = statement.executeUpdate(); // 返回结果的含义：这个操作影响到了几行
        System.out.println("ret = " + ret);

        /**5. 断开和数据库的连接，并且释放必要的资源。*/
        statement.close();
        connection.close(); //当连接不再使用，就需要释放连接，把之前的记录“擦除掉”。
    }
}
